/*
 从5442网站上把所有的热门推荐下载下来 async+cheerio+request
 */
 const util = require('util');
 const request = require('request');
 const http = require('http');
 const fs = require('fs');
 const cheerio = require('cheerio');
 const async = require('async');
 const mkdirp = require('mkdirp');
  
 function Picture5442() {
     this.host = 'http://www.5442.com/meinv/';
 }
  
 Picture5442.prototype = {
     main: function () {
         var self = this;
  
         async.auto({
             //如果是对象，需要进行绑定，否则this没有
             readIndex: self.readIndex.bind(self),
             downloadHot: ['readIndex', self.downloadHot.bind(self),],
         }, function (err, result) {
             if (err) {
                 console.error(err);
             } else {
                 //console.log(util.inspect(result, true));
                 console.log('所有的任务都完成');
             }
         });
     },
  
     //从主页读取要下载的内容
     readIndex: function (callback) {
         request(this.host, function (err, res, body) {
             if (!err && res.statusCode == 200) {
                 var $ = cheerio.load(body);
                 var links = $('div.lists.listNum.listTime.listLine a');
                 var linkArr = [];
                 links.each(function (i) {
                     linkArr[i] = $(this).attr('href');
                 });
  
                 //console.log('links=', util.inspect(linkArr,true));
                 linkArr.push('http://www.5442.com/meinv/20140802/11261.html');
                 linkArr.push('http://www.5442.com/meinv/20140705/10361.html');
                 callback(null, linkArr);
             } else {
                 callback(err);
             }
         });
     },
  
     //下载所有热门
     downloadHot: function (result, callback) {
         var self = this;
         var urls = result.readIndex;
         if (urls.length < 1) {
             callback('没有有效链接,读取失败', null);
             return;
         }
  
         async.auto({
             getAllFirstImage: self.getAllFirstImage.bind(self, urls),
             downloadImages: ['getAllFirstImage', self.downloadImages.bind(self)],
         }, function (err, results) {
             console.log('所有的热门图片已经下载完成');
             callback();
         });
     },
  
     //下载一个影集
     downloadGallery: function (aurl, callback) {
         //使用while循环，直到下载不到正确的结果的时候就退出循环
         if(!aurl){
             callback();
         }
  
         var nexturl = aurl;
         var parentcb = callback;
         var dirname;
         var m = aurl.match(/^http:\/\/.+\/(.+\/.+\/.+)\/(\d+\.jpg)/);
         if (!m) {
             callback('无效url地址，无法解析:' + aurl, null);
         } else {
             dirname = m[1];
         }
  
         async.auto(
             {
                 init: function (callback) {
                     //创建目录结构
                     if (!fs.existsSync(dirname)) {
                         mkdirp(dirname, function (err) {
                             if (err) {
                                 console.error(err);
                                 parentcb(err, null);
                                 return;
                             } else {
                                 console.log('创建目录成功：' + dirname);
                                 callback();
                             }
                         });
                     } else {
                         //不需要创建目录
                         callback();
                     }
                 },
  
                 work: ['init', function (result, callback) {
                     var flagExit = false;
                     async.during(
                         function (callback) {
                             callback(null, !flagExit);
                         },
                         function (callback) {
                             console.log('开始下载:' + nexturl);
                             //request.get(nexturl).pipe()
                             http.get(nexturl, function (res) {
                                 var chunks = [];
                                 if (res.statusCode !== 200) {
                                     //退出循环
                                     console.error('下载图片失败，认为已经没有可以下载的图片了:' + nexturl);
                                     flagExit = true;
                                     //直接调用回调函数退出，避免重复回调
                                     callback();
                                     return;
                                 }
  
                                 res.on('data', function (data) {
                                     chunks.push(data);
                                 });
  
                                 res.on('end', function () {
                                     var buf = Buffer.concat(chunks);
                                     var m = nexturl.match(/^http:\/\/.+\/(.+\/.+\/.+)\/(\d+\.jpg)/);
                                     var filename = m[1] + '/' + m[2];
                                     fs.writeFile(filename, buf, function () {
                                         console.log('保存图片到文件:' + filename);
                                         var m = nexturl.match(/(\d+)\.jpg$/);
                                         var nj;
                                         if (m[1][0] === '0') {
                                             if (m[1][1] < 9) {
                                                 nj = '0' + (parseInt(m[1][1]) + 1);
                                             } else {
                                                 nj = 10;
                                             }
  
                                         } else {
                                             nj = parseInt(m[1]) + 1 + '';
                                         }
                                         nj += '.jpg'
                                         //下一张图片的位置
                                         nexturl = nexturl.replace(/\d+\.jpg/, nj);
                                         callback();
                                     });
                                 });
  
                             })
                         },
                         function (err) {
                             console.log('跳出循环：' + aurl);
                             callback();
                         }
                     );
                 }],
             },
             function (err, result) {
                 if (err) {
                     console.error(err);
                     parentcb(err, aurl);
                 } else {
                     console.log('一个影集已经下载完成:' + aurl);
                     parentcb(null, aurl);
                 }
             });
  
     },
  
     //下载所有的图片
     downloadImages: function (results, callback) {
         if ('getAllFirstImage' in results) {
             //根据第一张图片开始不断的下载
             var urls = results.getAllFirstImage;
             async.mapSeries(urls, this.downloadGallery.bind(this), function (err, results) {
                 if (err) {
                     callback(err, null);
                 } else {
                     //返回所有成功的结果回去
                     callback(null, results);
                 }
             });
         } else {
             callback('获取不到第一张图片的数据', null);
         }
     },
  
     //读取页面的第一张图片，剩下的累加操作
     getFirstImage: function (aurl, callback) {
         request(aurl, function (err, res, body) {
             if (!err && res.statusCode == 200) {
                 var $ = cheerio.load(body);
                 var images = $('#contents img');
                 var firstImg = images.first().attr('src');
                 var flagIndex = firstImg.lastIndexOf('!');
                 if (flagIndex != -1) {
                     firstImg = firstImg.slice(0, flagIndex);
                 }
                 callback(null, firstImg);
             } else {
                 console.error(err);
                 callback(err, null);
             }
         });
     },
  
     //读取所有的第一张图片
     getAllFirstImage: function (urls, callback) {
         async.mapLimit(urls, 4, this.getFirstImage.bind(this), function (err, results) {
             //console.log('已经获取到所有的第一张图片地址');
             console.log('所有的第一张图片地址:' + util.inspect(results, true));
             callback(null, results);
         });
     }
 }
  
 var pic = new Picture5442()
 pic.main();